<?php
namespace Pc\Controller;
use Think\Controller;
/**
 * aws接口调用控制器 AwsController.class.php
 */
class AwsController extends Controller{
    /* 属性声明 */
    private $redis = null;
    private $token_cache_time = 1800;

    /* 方法声明 */
    public function __construct() {
        parent::__construct();
        $this -> access_key = C('AWS_KEY');
        $this -> secret = C('AWS_SECRET');
        $this -> request_url = C('AWS_URL');

        //初始化连接redis数据库
        $this -> redis = connectRedis();
    }
    
    /**
     * 连接aws生成待办接口
     */
    public function dealt($uuid,$username,$targetId){
        //$this -> url = $this -> url . '/uuid/' . $uuid;
        //当前时间戳 毫秒级

        $timestamp = round(microtime(true)*1000);
        //生成json数据 去掉之前的URL
        $json = "{'uuid':'{$uuid}','username':'{$username}','targetId':'{$targetId}'}";
        //构造签名串
        $code = "{$this->secret}access_key{$this->access_key}cmdhrms.createAuditTaskformatjsonsig_methodHmacMD5timestamp{$timestamp}zparams{$json}";
        //生成HMACMD5签名
        $sig = strtoupper(hash_hmac('md5',$code,$this->secret));
        //组织请求url
        $url = 
        "{$this->request_url}?timestamp={$timestamp}&sig_method=HmacMD5&cmd=hrms.createAuditTask&access_key={$this->access_key}&format=json&sig={$sig}&zparams={$json}";
        $result = json_decode(file_get_contents($url),true);
        //dump($result);exit;
        if($result['result']=='ok'){
            $awsid = json_decode($result['data'],true)['processInstanceId'];
            //dump($awsid);exit;
            return $awsid;
        }else{
            return false;
        }
    }
    
    /**
     * 提交员工信息审批结果
     * @param string 提交json字符串
     */
    public function terminal($data){
        $cmd = 'hrms.updateUserInfo';
        //当前时间戳 毫秒级
        $timestamp = round(microtime(true)*1000);
        //生成json数据
        $json = $data;
        //构造签名串
        $code = "{$this->secret}access_key{$this->access_key}cmd{$cmd}formatjsonsig_methodHmacMD5timestamp{$timestamp}zparams{$json}";
        //生成HMACMD5签名
        $sig = strtoupper(hash_hmac('md5',$code,$this->secret));
        //组织请求url
        $url = 
        "{$this->request_url}?timestamp={$timestamp}&sig_method=HmacMD5&cmd={$cmd}&access_key={$this->access_key}&format=json&sig={$sig}&zparams={$json}";
        $result = json_decode(file_get_contents($url),true);
        if($result['result']=='ok'){
            return $result['data'];
        }else{
            return false;
        }
    }
    
    public function HmacMd5($data,$key){   
        //需要配置环境支持iconv，否则中文参数不能正常处理   
        $key = iconv("GB2312","UTF-8",$key);   
        $data = iconv("GB2312","UTF-8",$data);   
        $b = 64; // byte length for md5   
        if (strlen($key) > $b) {   
            $key = pack("H*",md5($key));   
        }   
        $key = str_pad($key, $b, chr(0x00));   
        $ipad = str_pad('', $b, chr(0x36));   
        $opad = str_pad('', $b, chr(0x5c));   
        $k_ipad = $key ^ $ipad ;   
        $k_opad = $key ^ $opad;   
        return md5($k_opad . pack("H*",md5($k_ipad . $data)));   
    }

    /**
     * aws接口请求方法(获取员工信息,获取字典信息,获取子集与人员关系,时间字段验证) post提交数据
     */
    public function requestAws2($cmd,$data){
        //return $data;
        //当前时间戳 毫秒级
        $timestamp = round(microtime(true)*1000);
        //生成json数据
        $json = $data;
        //构造签名串
        $code = "{$this->secret}access_key{$this->access_key}cmd{$cmd}formatjsonsig_methodHmacMD5timestamp{$timestamp}zparams{$json}";
        //生成HMACMD5签名
        $sig = strtoupper(hash_hmac('md5',$code,$this->secret));
        //生成HMACMD5签名
        $pass = "timestamp={$timestamp}&sig_method=HmacMD5&cmd={$cmd}&access_key={$this->access_key}&format=json&sig={$sig}&zparams={$json}";
        $result = https_curl($this->request_url,$pass);
        //记录日志信息
        //@file_put_contents('./api_log.log',$result.'########\r\n',FILE_APPEND);

        $result = json_decode($result,true);
        //dump($result);exit;
        if($result['result']=='ok'){
            if(isset($result['data'])){
                $data = $result['data'];
                if(isset($data['err'])){
                    $list['type'] = 1;
                    $list['msg'] = $data['err'];
                    $this->error($data['err']);
                }else{
                    $list['type'] = 2;
                    $list['data'] = $result['data'];
                    return $list;
                }
            }
        }else{
            $list['type'] = 0;
            $list['msg'] = '接口错误';
            $this->error('接口错误');
        }
    }

    //aws回写大库接口
    public function Writeback($data){
        $cmd = 'hrms.updateUserInfo';
        $json = json_encode($data);
        //dump($json);exit;
        //当前时间戳 毫秒级
        $timestamp = round(microtime(true)*1000);
        //构造签名串
        $code = "{$this->secret}access_key{$this->access_key}cmd{$cmd}formatjsonsig_methodHmacMD5timestamp{$timestamp}zparams{$json}";
        //生成HMACMD5签名
        $sig = strtoupper(hash_hmac('md5',$code,$this->secret));
        //生成HMACMD5签名
        $pass = "timestamp={$timestamp}&sig_method=HmacMD5&cmd={$cmd}&access_key={$this->access_key}&format=json&sig={$sig}&zparams={$json}";
        $result = https_curl($this->request_url,$pass);
        //记录日志信息
        //@file_put_contents('./api_log.log',$result.'########\r\n',FILE_APPEND);

        $result = json_decode($result,true);
        //dump($result);exit;
        if($result['result']=='ok'){
            if(isset($result['data'])){
                return $result;
            }else{
                return true;
            }
        }else{
            return false;
        }
    }

    //检验审批结果接口
    public function jySpJg(){
        if(count($_POST)==1){
            $this -> data = json_decode(array_keys($_POST)[0],true);
        }else{
            $this -> data = $_POST;
        }
        $uuid = $this -> data['uuid'];
        $awsid = $this -> data['processInstanceId'];
//        $uuid = 'guohuichao';
//        $awsid = 'f191069d-3c9f-4985-90c0-353677bd8879';
        //echo json_encode($this->data);exit;
        if(!$uuid || !$awsid ){
            $return_info = [
                'sp_type' => false,
                'msg' => '参数缺失'
            ];
            echo json_encode($return_info);
            exit;
        }

        //获取未审批数据
        $resolt = $this->getSpInfo($awsid);

        echo json_encode($resolt);

    }

    //获取未审批数据
    protected function getSpInfo($awsid){
        //1.取出审批数据
        $this->redis->select(12);
        $sp_info = unserialize($this->redis->get('sp_'.$awsid));
        //dump($sp_info);

        //2.取出修改数据
        $this->redis->select(10);
        if(!$userinfo= $this->redis->get('change_'.$awsid)){
             $arr = [
                 'sp_type' => false,
                 'msg' => '当前员工的修改数据不存在!',
             ];
            return $arr;
        }
        $userlist = unserialize($userinfo)['information'];
        //dump($userlist);exit;
        //3.获取未审批的子集
        $wei_sp_info = [];
        foreach($userlist as $k=>$v){
            if(!array_key_exists($k,$sp_info)){
                $wei_sp_info[] = $v['caption'];
            }else{
                if($k != 'BO_CASC_HR_YGRS') {
                    if(count($v['subvalue']) != count($sp_info[$k]['sp_info'])){
                        $wei_sp_info[] = $v['caption'];
                    }
                }
            }
        }
        //dump($wei_sp_info);
        $arr = [
            'sp_type' => true,
            'info' => $wei_sp_info

        ];
        return $arr;
    }

    //最后办理审批接口
    public function handle(){
        if(count($_POST)==1){
            $this -> data = json_decode(array_keys($_POST)[0],true);
        }else{
            $this -> data = $_POST;
        }
        $awsid = $this -> data['awsid'];
        $yguuid = $this -> data['yguuid'];
        $signe = $this -> data['signe'];
        $time = $this -> data['time'];
        $randstr = $this -> data['randstr'];
//        $awsid = '8b781364-ba67-4b9c-9c59-a26d8e3edddd';
//        $yguuid = '9987654321';
        if(!$signe || !$time || !$randstr || !$awsid || !$yguuid ){
            $arr = [
                'type' => false,
                'msg' => '参数缺失'
            ];
            $this -> response_result($arr);
        }
        //接口验证
        $ip = $_SERVER['REMOTE_ADDR'];  //获取IP
        $newsigne = $this->arithmetic($time,$randstr,$awsid,$yguuid,$ip);
        if($newsigne != $signe){
            $arr = [
                'type' => false,
                'msg' => '非法调用接口!'
            ];
            $this -> response_result($arr);
        }

        /********************************获取redis数据************************************/
        //获取该流程修改数据
        $this -> redis -> select(11);
        if(!$info = unserialize($this->redis->hget('change_'.$yguuid,$awsid))){
            $arr = [
                'type' => false,
                'msg' => '员工修改信息获取失败!'
            ];
            $this -> response_result($arr);
        }
        //dump($info);
        //获取该流程审批数据
        $this->redis->select(12);
        if(!$sp_info = unserialize($this->redis->get('sp_'.$awsid))){
            $arr = [
                'type' => false,
                'msg' => '获取审核结果错误',
            ];
            $this -> response_result($arr);
        }
        //dump($sp_info);exit;

        /*******************************获取修改数据,调用接口回写大库**********************************/
        //1.获取已通过的修改数据
        $sptgChangeInfo = $this->getSptgChangeInfo($info,$sp_info);
        //绑定附件信息
        $sptgChangeInfo = $this->setFileInfo($sptgChangeInfo,$yguuid);
        //dump(json_encode($sptgChangeInfo));exit;

        if(count($sptgChangeInfo['info']['information']) != 0){
            //1.1 调用aws回写大库接口
            $fh_info = $this->Writeback($sptgChangeInfo['info']);
            if(!$fh_info){
                $return_info = [
                    'type' => false,
                    'msg' => '返回新增awsid接口错误'
                ];
                $this -> response_result($return_info);
            }
            //dump($fh_info);exit;
        }
        /*******************************整理redis数据,绑定新增的awsid**********************************/
        //2.整理redis数据
        $this->rewriteRedis($sp_info,$awsid,$yguuid,$fh_info['data']);

        //3.整理附件信息
        $this->setRedisFile($sp_info,$yguuid);

        /*******************************返回审批结果**********************************/
        //4.获取审批结果,返回
        $arr = $this->get_sp_info($sp_info,$yguuid);
        echo json_encode($arr);

    }

    //获取已通过的修改数据
    protected function getSptgChangeInfo($info,$sp_info){
        //dump($info);
        //dump($sp_info);exit;
        //2.筛选数据 得到已审批通过的修改数据
        $sx_data = $info['information'];
        foreach($sx_data as $k=>$v){
            if($k == 'BO_CASC_HR_YGRS'){
                foreach($v['sublist'] as $h=>$j){
                    if($sp_info[$k]['sp_info'][$h]['sp_type'] == 0){
                        unset($sx_data[$k]['sublist'][$h]);
                    }
                }
                if(count($sx_data[$k]['sublist']) == 0){
                    unset($sx_data[$k]);
                }
            }else{
                $status = $v['status'];
                $subval = $v['subvalue'];
                foreach($subval as $h=>$j){
                    if($sp_info[$k]['sp_info'][$h]['sp_type'] == 0){
                        unset($sx_data[$k]['subvalue'][$h]);

                        $status = $this->setStatus($h,$status,$j['awsid']);
                    }
                }
                //整理status数据
                $sx_data[$k]['status'] = $status;

                //如果没有通过的记录,删除该子集
                if(count($sx_data[$k]['subvalue']) == 0){
                    unset($sx_data[$k]);
                }
            }
        }

        $sp_tg_info['uuid'] = $info['uuid'];
        $sp_tg_info['information'] = $sx_data;
        //dump($sp_tg_info);exit;
        $arr = [
            'info' => $sp_tg_info
        ];
       return $arr;
    }

    //绑定附件信息
    protected function setFileInfo($sptgChangeInfo,$yguuid){
        $keys = array_keys($sptgChangeInfo['info']['information']);
        foreach($keys as $k=>$v){
            $this->redis->select(9);
            $file_info = unserialize($this->redis->hget('file_'.$yguuid,$v));
            $arr = [];
            foreach($file_info as $a=>$b){
                foreach($b as $h=>$j){
                    $str = '';
                    foreach($j as $q=>$w){
                        if($w['status'] == 2 || $w['status'] == 3){
                            $str.= $q.'@@'.$w['href'].'--';
                        }elseif($w['status'] == 4 ){
                            $str.= $q.'@@'.'false'.'--';
                        }
                    }
                    $arr[$a][$h] = rtrim($str,'--');
                }
            }
//            dump($arr);exit;
//            if($v == 'BO_CASC_HR_YGRS'){
//                foreach($sptgChangeInfo['info']['information'][$v]['sublist'] as $k1=>$v1){
//                    if($v1['type'] == 'FILE'){
//                        $sptgChangeInfo['info']['information'][$v]['sublist'][$k1]['value'] = $arr[0][$k1];
//                    }
//                }
//            }else{
//                foreach($sptgChangeInfo['info']['information'][$v]['subvalue'] as $k1=>$v1){
//                    foreach($v1['info'] as $k2=>$v2){
//                        if($v2['type'] == 'FILE'){
//                            $sptgChangeInfo['info']['information'][$v]['subvalue'][$k1]['info'][$k2]['value'] = $arr[$k1][$k2];
//                        }
//                    }
//                }
//            }
            foreach($arr as $k1=>$v1){
                if($v == 'BO_CASC_HR_YGRS'){
                    foreach($v1 as $k2=>$v2){
                        if($v2){
                            if($sptgChangeInfo['info']['information'][$v]['sublist'][$k2]){
                                $sptgChangeInfo['info']['information'][$v]['sublist'][$k2]['value'] = $arr[$k1][$k2];
                            }
                        }
                    }
                }else{
                    foreach($v1 as $k2=>$v2){
                        if($v2){
                            if($sptgChangeInfo['info']['information'][$v]['subvalue'][$k1]){
                                $sptgChangeInfo['info']['information'][$v]['subvalue'][$k1]['info'][$k2]['value'] = $arr[$k1][$k2];
                            }
                        }
                    }
                }
            }
        }

        return $sptgChangeInfo;
    }

    //整理 重写redis
    private function rewriteRedis($sp_info,$awsid,$uuid,$insterawsid){
        //取出当前uuid的员工入司数据
        $this->redis->select(10);
        if(!$data = json_decode($this->redis->hget('user_list',$uuid),true)){
            $arr = [
                'type' => false,
                'msg' => '获取员工数据失败!'
            ];
            return $arr;
        }
        //dump($data);exit;
        $info = $data['information'];
        //dump($sp_info);exit;

        foreach($sp_info as $k=>$v){
            //员工基本信息
            if($k == 'BO_CASC_HR_YGRS'){
                $tob =0;
                $reasons = '';
                foreach($v['sp_info'] as $t=>$f){
                    if($f['sp_type'] == 1){
                        $info[$k]['sublist'][$t]['change_type'] = 0;
                    }else{
                        $tob++;
                        $reasons .= $f['reason'].',';
                    }
                }
                if($tob == 0){
                    $info[$k]['change_type'] = 0;
                    $info[$k]['sp_type'] = 1;
                    unset($info[$k]['reason']);
                }else{
                    $info[$k]['sp_type'] = 0;
                    $info[$k]['reason'] = rtrim($reasons,',');
                }
                //dump($info[$k]);exit;
            }else{
                //子集信息
                $status = $info[$k]['status'];
                //dump($status);exit;
                $toa = 0;
                foreach($v['sp_info'] as $h=>$j){
                    $sub_info = $info[$k]['subvalue'][$h]['info'];
                    if($j['sp_type'] == 1){
                        //绑定新增的awsid
                        if($insterawsid[$k][$h]){
                            $info[$k]['subvalue'][$h]['awsid'] = $insterawsid[$k][$h];
                        }
                        foreach($sub_info as $a=>$b){
                            if($b['change_type'] == 1){
                                $info[$k]['subvalue'][$h]['info'][$a]['change_type'] = 0;
                            }
                        }

                        $info[$k]['subvalue'][$h]['change_type'] = 0; //修改状态为0
                        $info[$k]['subvalue'][$h]['sp_type'] = 1;  //审批状态为1
                        unset($info[$k]['subvalue'][$h]['reason']);
                        //整理status数据,
                        $status = $this->setStatus($h,$status,$info[$k]['subvalue'][$h]['awsid']);
                    }else{
                        $toa++;
                        //如果是删除的没通过
                        if($info[$k]['subvalue'][$h]['no_display']){
                            $toa--;
                            foreach($sub_info as $a=>$b){
                                if($b['change_type'] == 1){
                                    //如果有更改,恢复原值
                                    $info[$k]['subvalue'][$h]['info'][$a]['value'] = $info[$k]['subvalue'][$h]['info'][$a]['oldvalue'];
                                    $info[$k]['subvalue'][$h]['info'][$a]['change_type'] = 0;
                                }
                            }
                            unset($info[$k]['subvalue'][$h]['no_display']);
                            $info[$k]['subvalue'][$h]['change_type'] = 0;  //审批状态为0
                            //把delete里的数量删除
                            unset($status['delete'][$h]);
                        }
                        $info[$k]['subvalue'][$h]['sp_type'] = 0;  //审批状态为0
                        $info[$k]['subvalue'][$h]['reason'] = $v['sp_info'][$h]['reason'];  //审批状态为1
                    }
                }
                if($toa == 0){
                    $info[$k]['change_type'] = 0;
                }
                $info[$k]['status'] = $status;
            }
        }
        //dump($info);exit;
        $data['information'] = $info;
        //重新保存员工json数据
        $this->redis->select(10);
        $this->redis->hset('user_list',$uuid,json_encode($data));

        //删除保存的子集名
        $this->redis->select(11);
        $this->redis->hdel('items_'.$uuid,$awsid);

        //保存审批结束的流程id
        $this->redis->select(12);
        $sp_js_info = unserialize($this->redis->get('sp_js_'.$uuid));
        $sp_js_info[] = $awsid;
        $this->redis->set('sp_js_'.$uuid,serialize($sp_js_info));
    }

    //更改status数据
    protected function setStatus($key,$status,$awsid){
        $insertid = array_search($key,$status['insert']);
        if($insertid !== false){
            unset($status['insert'][$insertid]);
        }else{
            $updateid = array_search($key,$status['update']);
            if($updateid !== false){
                unset($status['update'][$updateid]);
            }else{
                $delid = array_search($awsid,$status['delete']);
                unset($status['delete'][$delid]);
            }
        }
        return $status;
    }

    //更改redis附件信息
    private function setRedisFile($sp_info,$uuid){
        $keys = array_keys($sp_info);
        foreach($keys as $k=>$v){
            $this->redis->select(9);
            $file_info = unserialize($this->redis->hget('file_'.$uuid,$v));
            if($v == 'BO_CASC_HR_YGRS'){
                foreach($sp_info[$v]['sp_info'] as $k1=>$v1){
                    if($v1['sp_type'] == 1){
                        foreach($file_info[0][$k1] as $k2=>$v2){
                            if($file_info[0][$k1][$k2]['status'] == 2 || $file_info[0][$k1][$k2]['status'] == 3){
                                $file_info[0][$k1][$k2]['status'] = 1;
                            }elseif($file_info[0][$k1][$k2]['status'] == 4){
                                unset($file_info[0][$k1][$k2]);
                            }
                        }
                    }else{
                        foreach($file_info[0][$k1] as $k2=>$v2){
                            if($file_info[0][$k1][$k2]['status'] == 4 ){
                                $file_info[0][$k1][$k2]['status'] = 1;
                            }
                        }
                    }
                }
                //dump($file_info);exit;
            }else{
                foreach($sp_info[$v]['sp_info'] as $k1=>$v1){
                    if($v1['sp_type'] == 1){
                        foreach($file_info[$k1] as $k2=>$v2){
                            foreach($v2 as $k3=>$v3){
                                if($file_info[$k1][$k2][$k3]['status'] == 2 || $file_info[$k1][$k2][$k3]['status'] == 3){
                                    $file_info[$k1][$k2][$k3]['status'] = 1;
                                }elseif($file_info[$k1][$k2][$k3]['status'] == 4){
                                    unset($file_info[$k1][$k2][$k3]);
                                }
                            }
                        }
                    }else{
                        foreach($file_info[$k1] as $k2=>$v2){
                            foreach($v2 as $k3=>$v3){
                                if($file_info[$k1][$k2][$k3]['status'] == 4){
                                   $file_info[$k1][$k2][$k3]['status'] = 1;
                                }
                            }
                        }
                    }
                }
                //dump($file_info);exit;
            }
            $this->redis->select(9);
            $this->redis->hset('file_'.$uuid,$v,serialize($file_info));
            //dump($file_info);
        }

    }

    //返回审批结果数据接口
    public function get_sp_info($sp_info,$uuid){
        //dump($sp_info);exit;
        $row = [];
        foreach($sp_info as $k=>$v){
            $row[] = $v['caption'];
        }
        $arr = [
            'type' => true,
            'info' => $row,
            'uuid' => $uuid
        ];
        return $arr;
    }

    /* 生成token */
    public function getToken(){
        if(count($_POST) == 1){
            $data = json_decode(array_keys($_POST)[0],true);
        }else{
            $data = $_POST;
        }

        //检测参数是否存在
        $action = $data['action'];
        if(!$action){
            $arr = [
                'type' => false,
                'msg'  => '参数缺失!'
            ];
            $this ->response_result($arr);
        }
        //生成token
        $token = md5(time().$action.mt_rand(1111,9999));

        //记录客户端ip
        $token_info['expires'] = $this -> token_cache_time;
        $token_info['remote_ip'] = $_SERVER['REMOTE_ADDR'];
        $token_info['token'] = $token;

        S($action.$token,$token_info,$this->token_cache_time);
        $arr = [
            'type' => true,
            'token' => $token
        ];
        $this ->response_result($arr);
    }

    /**
     * 检测用户token合法性
     */
    public function check_token($action,$token){
        //检测token合法性
        $token_info = S($action.$token);
        if($token != $token_info['token']){
            $arr = [
                'type' => false,
                'msg' => 'token缺失或者token过期,请尝试重新登录'
            ];
            return $arr;
        }
        //检测请求端ip地址
        $original_remote_ip = $token_info['remote_ip'];
        $current_remote_ip = $_SERVER['REMOTE_ADDR'];
        //dump($current_remote_ip);exit;
//        if($original_remote_ip != $current_remote_ip){
//            $arr = [
//                'type' => false,
//                'msg' => '拒绝可疑的token请求'
//            ];
//            return $arr;
//        }
        $arr = [
            'type' => true,
        ];
        return $arr;
    }

    //返回数据
    private function response_result($arr){
        echo json_encode($arr,JSON_UNESCAPED_UNICODE);
        exit;
    }

    /**
     * @param $timeStamp 时间戳
     * @param $randomStr 随机字符串
     * @param $ip 访问者IP
     * @param $awsid 流程ID
     * @param $awsid 员工ID
     * @return string 返回签名
     */
    private function arithmetic($timeStamp,$randomStr,$awsid,$yguuid,$ip){
        $arr['timeStamp'] = $timeStamp;
        $arr['randomStr'] = $randomStr;
        $arr['key'] = C('AWS_KEY');
        $arr['awsid'] = $awsid;
        $arr['uuid'] = $yguuid;
        $arr['ip'] = $ip;

        //按照首字母大小写顺序排序
        sort($arr,SORT_STRING);
        //拼接成字符串
        $str = implode($arr);
        //dump($str);exit;
        //进行加密
        $signature = sha1($str);
        $signature = md5($signature);
        //转换成大写
        $signature = strtoupper($signature);
        //dump($signature);exit;
        return $signature;
    }

}